//
// Created by 29019 on 2020/4/18.
//

#ifndef GENERAL_TCPCLIENT_H
#define GENERAL_TCPCLIENT_H

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#ifdef linux
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#define EVENT__HAVE_PTHREADS
#endif

extern  "C"{
    #include "event2/bufferevent.h"
    #include "event2/buffer.h"
    #include "event2/listener.h"
    #include "event2/util.h"
    #include "event2/event.h"
    #include "event2/thread.h"
};
#include<string.h>
#include <iostream>
// #include "PackageReceiver.h"
#include <mutex>
#include <thread>
using  namespace std;

class TcpClientLibevent {
public:
    typedef enum {
		UNCONNECTED,  // 未连接
		CONNECTED, //已经连接
		FAIL,       // 连接失败
    }Status;
    class TcpClientObserver{
    public:
        virtual ~TcpClientObserver(){return;}
        mutex mMux;
        virtual void OnConnected() { return; };
        virtual void OnDisConnected() { return; };
        virtual void OnData(uint8_t *dat,uint64_t len){return;};
        virtual void OnClose(){return;};
    };
    TcpClientLibevent(std::string addrinfo,int port, TcpClientObserver *p);
    ~TcpClientLibevent(){
        event_base_free(mBase);
    };
    int ConnectServer();
    bool Connected();
    int Dispatch();
    int OnTCPPackage(uint8_t *, uint16_t);
    int SetReconnect(bool);
    int SetObserver(TcpClientObserver*);
    int Close();
    Status mStatus;
    TcpClientObserver *mObserver;
private:
    bool mReConnect = false;
    int sendData(void*,size_t);
    struct event_base *mBase;
    struct bufferevent* bev;
    struct sockaddr_in mSrv;
    std::thread *mThread;
    mutex mLock;
};

#endif //GENERAL_TCPCLIENT_H
